﻿using AutoMapper;
using IOA.MES.Common;
using IOA.MES.DataAccess.Entity;
using IOA.MES.DataAccess.Enum;
using IOA.MES.DataAccess.VModel;
using System;
using System.Collections.Generic;
using System.Linq;

namespace IOA.MES.Business
{
    /// <summary>
    /// 模块管理（错误代码：118001）
    /// </summary>
    public class ModuleMgr
    {
        private MESContext mesDb = new MESContext("MES");

        /// <summary>
        /// 查询用户模块
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns>模块列表</returns>
        public List<VModule> GetModuleTree(int userId)
        {
            var user = mesDb.Users.FirstOrDefault(_ => _.PkId == userId && _.Valid);
            if (user == null || user.Status != CommonStatus.Normal)
            {
                return new List<VModule>();
            }
            var roleIds = mesDb.UserRoles.Where(_ => _.UserId == user.PkId && _.Valid).Select(_ => _.RoleId).ToList();
            var allModules = Mapper.Map<List<VModule>>(mesDb.Modules.Where(_ => _.Valid).ToList()).OrderBy(_ => _.ParentId).ThenByDescending(_ => _.SortNo).ToList();
            var roleModules = new List<VModule>();
            if (roleIds.Contains(1))
            {
                roleModules.AddRange(allModules);
            }
            else
            {
                roleModules.AddRange(Mapper.Map<List<VModule>>((from rm in mesDb.RoleModules.Where(_ => _.Valid && roleIds.Contains(_.RoleId))
                                                                join m in mesDb.Modules.Where(_ => _.Anonymous == false && _.Valid) on rm.ModuleId equals m.PkId
                                                                select m).ToList()));
                var moduleIds = roleModules.Select(_ => _.PkId).Distinct().ToList();
                roleModules.AddRange(Mapper.Map<List<VModule>>(mesDb.Modules.Where(_ => _.Anonymous && _.Valid).ToList()));
            }
            roleModules = roleModules.OrderBy(_ => _.ParentId).ThenByDescending(_ => _.SortNo).ToList();
            allModules.ForEach(_ => _.DisplayTitle = string.Equals("English", user.Language, StringComparison.CurrentCultureIgnoreCase) ? _.ENTitle : (string.Equals("Tiếngviệt", user.Language, StringComparison.CurrentCultureIgnoreCase) ? _.VNTitle : _.CNTitle));
            roleModules.ForEach(_ => _.DisplayTitle = string.Equals("English", user.Language, StringComparison.CurrentCultureIgnoreCase) ? _.ENTitle : (string.Equals("Tiếngviệt", user.Language, StringComparison.CurrentCultureIgnoreCase) ? _.VNTitle : _.CNTitle));
            return CreateTree(allModules, roleModules, 0);
        }

        private List<VModule> CreateTree(List<VModule> allModules, List<VModule> roleModules, int parentId)
        {
            var result = new List<VModule>();
            foreach (var module in allModules.Where(_ => _.ParentId == parentId).ToList())
            {
                if (string.IsNullOrWhiteSpace(module.Url))
                {
                    var subModules = CreateTree(allModules, roleModules, module.PkId);
                    if (subModules.Any())
                    {
                        module.SubModules.AddRange(subModules);
                        result.Add(module);
                    }
                }
                else
                {
                    if (roleModules.Any(_ => _.PkId == module.PkId))
                    {
                        result.Add(module);
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// 查询权限列表
        /// </summary>
        /// <returns>权限列表</returns>
        public List<VModule> QueryModules(int userId)
        {
            var userRoles = (from u in mesDb.Users.AsNoTracking()
                             join ur in mesDb.UserRoles.AsNoTracking() on u.PkId equals ur.UserId
                             join r in mesDb.Roles.AsNoTracking() on ur.RoleId equals r.PkId
                             where u.Valid && u.PkId == userId && ur.Valid && r.Valid && r.IsManager
                             select r).ToList();
            if (!userRoles.Any())
            {
                return new List<VModule>();
            }

            var entities = new List<Module>();
            if (userRoles.Any(_ => _.PkId == 1))
            {
                entities = mesDb.Modules.AsNoTracking().Where(_ => _.Valid).OrderBy(_ => _.ParentId).ThenByDescending(_ => _.SortNo).ToList();
            }
            else
            {
                var departmentIds = new DepartmentMgr().QueryUserDepartments(userId).Select(_ => _.PkId).Distinct().ToList();
                departmentIds.Add(0);
                entities = mesDb.Modules.AsNoTracking().Where(_ => departmentIds.Contains(_.DepartmentId) && _.Valid).OrderBy(_ => _.ParentId).ThenByDescending(_ => _.SortNo).ToList();
            }
            return Mapper.Map<List<VModule>>(entities);
        }

        /// <summary>
        /// 保存岗位权限
        /// </summary>
        /// <param name="roleId">岗位ID</param>
        /// <param name="moduleIds">模块ID列表</param>
        /// <param name="operator">操作人</param>
        public void SaveRoleModules(int roleId, List<int> moduleIds, int @operator)
        {
            var role = new RoleMgr().GetRole(roleId);
            if (role == null)
            {
                throw new MultiLanBizException(118001);//岗位不存在
            }
            moduleIds = mesDb.Modules.Where(_ => _.Valid).ToList().Where(_ => moduleIds.Contains(_.PkId) && !string.IsNullOrWhiteSpace(_.Url)).Select(_ => _.PkId).ToList();

            var existModules = mesDb.RoleModules.Where(_ => _.RoleId == roleId && _.Valid).ToList();
            var removeModules = existModules.Where(_ => !moduleIds.Contains(_.ModuleId)).ToList();
            var newModules = moduleIds.Where(_ => !existModules.Select(m => m.ModuleId).Contains(_)).Select(_ => new RoleModule
            {
                RoleId = roleId,
                ModuleId = _,
                CreateBy = @operator,
                CreateTime = DateTime.Now,
                DepartmentId = role.DepartmentId
            }).ToList();

            removeModules.ForEach(_ =>
            {
                _.Valid = false;
                _.ModifyBy = @operator;
                _.ModifyTime = DateTime.Now;
            });
            mesDb.RoleModules.AddRange(newModules);
            mesDb.SaveChanges();
        }

        /// <summary>
        /// 查询岗位权限
        /// </summary>
        /// <param name="roleId">岗位ID</param>
        /// <returns>权限列表</returns>
        public List<VRoleModule> QueryRoleModules(int roleId)
        {
            var entities = mesDb.RoleModules.Where(_ => _.RoleId == roleId && _.Valid).ToList();
            return Mapper.Map<List<VRoleModule>>(entities);
        }
    }
}
